'''
Created on Mar 18, 2011

@author: oabalbin
'''
import sys
from collections import defaultdict
from optparse import OptionParser

def vcf_header():
    '''
    ##fileformat=VCFv4.0
    ##FILTER=<ID=HARD_TO_VALIDATE,Description="MQ0 >= 4 && ((MQ0 / (1.0 * DP)) > 0.1)">
    ##FILTER=<ID=InDel,Description="Overlaps a user-input mask">
    ##FILTER=<ID=LowQual,Description="Low quality">
    ##FILTER=<ID=STAND_FILTER,Description="QUAL < 30.0 || QD < 5.0 || HRun > 5 || SB > -0.10">
    ##FILTER=<ID=SnpCluster,Description="SNPs found in clusters">
    ##FORMAT=<ID=AD,Number=.,Type=Integer,Description="Allelic depths for the ref and alt alleles in the order listed">
    ##FORMAT=<ID=DP,Number=1,Type=Integer,Description="Read Depth (only filtered reads used for calling)">
    ##FORMAT=<ID=GL,Number=3,Type=Float,Description="Log-scaled likelihoods for AA,AB,BB genotypes where A=ref and B=alt; not applicable if site is not biallelic">
    ##FORMAT=<ID=GQ,Number=1,Type=Float,Description="Genotype Quality">
    ##FORMAT=<ID=GT,Number=1,Type=String,Description="Genotype">
    ##INFO=<ID=AB,Number=1,Type=Float,Description="Allele Balance for hets (ref/(ref+alt))">
    ##INFO=<ID=AC,Number=.,Type=Integer,Description="Allele count in genotypes, for each ALT allele, in the same order as listed">
    ##INFO=<ID=AF,Number=.,Type=Float,Description="Allele Frequency, for each ALT allele, in the same order as listed">
    ##INFO=<ID=AN,Number=1,Type=Integer,Description="Total number of alleles in called genotypes">
    ##INFO=<ID=DP,Number=1,Type=Integer,Description="Total Depth">
    ##INFO=<ID=DS,Number=0,Type=Flag,Description="Were any of the samples downsampled?">
    ##INFO=<ID=Dels,Number=1,Type=Float,Description="Fraction of Reads Containing Spanning Deletions">
    '''
    header=['##fileformat=VCFv4.0','#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO']
    
    return header
    

def read_line(l, fdict):
    '''
    '''
    d = defaultdict()
    f = l.strip('\n').split('\t')
    for i,v in fdict.iteritems():
        d[i] = f[v]
    return d

def print_line(fdict,fields):
    '''
    '''
    # Mandatory fields
    mand_f=['ID','CHROM','POS','REF','ALT','QUAL','FILTER'] # ,'FORMAT':'None', 'SAMPLE':'unknown'
    
    mf = [fields['CHROM'],fields['POS'],fields['ID'], 
      fields['REF'], fields['ALT'], fields['QUAL'],
      fields['FILTER']]
    
    opt_f=[]
    for key,val in fields.iteritems():
        if key not in mand_f:
            opt_f.append(key+'='+val)
    mf=mf+[",".join(opt_f).replace(',',';')]
    
    return mf

def print_bed_line(fdict,fields):
    '''
    '''
        # Mandatory fields
    mand_f=['ID','CHROM','POS','REF','ALT','QUAL','FILTER'] # ,'FORMAT':'None', 'SAMPLE':'unknown'
    
    mf = [fields['CHROM'],fields['POS'],fields['ID'], 
      fields['REF'], fields['ALT'], fields['QUAL'],
      fields['FILTER']]
    
    opt_f=[]
    for key,val in fields.iteritems():
        if key not in mand_f:
            opt_f.append(key+'='+val)
    bed = [fields['CHROM'],fields['POS'], str(int(fields['POS'])+1)]
    mf=[",".join(mf+[",".join(opt_f).replace(',',';')]).replace(',','|')]
    mf=bed+mf
    
    return mf

        
    
def read_file(ifile, ofile):
    '''
    Mandatory fields
    #CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO
    Optional fields
      FORMAT  am59_null
    
    '3/0/0/0', '3/0/0/0', '50/0/0/0', '50/0/0/0', '3/0/0/0', '3/0/0/0'
    

    '''
    # Fragments equal to Depth of coverage
    fdict={'ID':1,'CHROM':5,'POS':6,'REF':8,'ALT':2,'FRAG':3,
          'VF':4,'DP':3,'QUAL':4,'FILTER':7} # ,'FORMAT':'None', 'SAMPLE':'unknown'
    FRAG_th, VF_th = 6, 0.1
    #i = 0
    ofile.write( ",".join(vcf_header()).replace(',','\n')+'\n')
    for l in ifile:
        fields = read_line(l, fdict)
        if int(fields['FRAG']) >= FRAG_th and float(fields['VF']) >= VF_th:
            ofile.write( ",".join(print_line(fdict,fields)).replace(',','\t')+'\n') 
        

def read_file_bed(ifile, ofile):
    '''
    Mandatory fields
    #CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO
    Optional fields
      FORMAT  am59_null
    
    '3/0/0/0', '3/0/0/0', '50/0/0/0', '50/0/0/0', '3/0/0/0', '3/0/0/0'
    '''
    # Fragments equal to Depth of coverage
    fdict={'ID':1,'CHROM':5,'POS':6,'REF':8,'ALT':2,'FRAG':3,
          'VF':4,'DP':3,'QUAL':4,'FILTER':7} # ,'FORMAT':'None', 'SAMPLE':'unknown'
    FRAG_th, VF_th = 6, 0.1
    #i = 0
    #ofile.write( ",".join(vcf_header()).replace(',','\n')+'\n')
    for l in ifile:
        fields = read_line(l, fdict)
        if int(fields['FRAG']) >= FRAG_th and float(fields['VF']) >= VF_th:
            ofile.write( ",".join(print_bed_line(fdict,fields)).replace(',','\t')+'\n') 


if __name__ == '__main__':
    
    optionparser = OptionParser("usage: %prog [options] ")
    optionparser.add_option("-i", "--input_file", dest="input_file",
                            help="file with run configuration")
    optionparser.add_option("-o", "--output_file", dest="output_file",
                        help="file with run configuration")
    optionparser.add_option("--print_bed", dest="print_bed", action="store_true", default=False,
                            help="print_bed") 
            
    (options, args) = optionparser.parse_args()
    
    if not options.print_bed:
        read_file(open(options.input_file),open(options.output_file,'w'))
    else:
        read_file_bed(open(options.input_file),open(options.output_file,'w'))